package com.sunrise.gateway.commons;

import com.dap.cache.common.RedisComponentInterface;
import com.dap.exception.BusinessException;
import com.dap.param.ControlData;
import com.dap.param.StringInput;
import com.dap.utils.LongStringIdUtil;
import com.dap.utils.SpringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

/**
 * Created by wangmin on 2019/2/22.
 */
public abstract class SessionRequestExtraAuthUtil {
    private final static Logger logger = LoggerFactory.getLogger(SessionRequestExtraAuthUtil.class);

    public static String resolveExtraAuthToken() {
        try {
            Subject subject = SecurityUtils.getSubject();
            if (null == subject) {
                return null;
            }
            Session session = subject.getSession(false);
            if (session == null) {
                return null;
            }
            String sessionId = session.getId().toString();

            RedisComponentInterface redisComponentInterface = SpringUtils.getBean(RedisComponentInterface.class);

            return resolveExtraAuthToken(sessionId, redisComponentInterface);
        } catch (Throwable throwable) {
            logger.error("", throwable);
            return null;
        }
    }
    public static String resolveExtraAuthToken(String sessionId, RedisComponentInterface redisComponentInterface) {
        try {
            String token = redisComponentInterface.get(Constants.SESSION_REQUEST_EXTRA_AUTH_TOKEN_KEY, sessionId, String.class);
            if (!StringUtils.isEmpty(token)) {
                return token;
            }

            token = LongStringIdUtil.generateId();
            String setResult = redisComponentInterface.setnxExpire(
                    Constants.SESSION_REQUEST_EXTRA_AUTH_TOKEN_KEY, sessionId, 3600 * 1000, token);
            if ("OK".equals(setResult)) {
                return token;
            } else {
                return redisComponentInterface.get(Constants.SESSION_REQUEST_EXTRA_AUTH_TOKEN_KEY, sessionId, String.class);
            }
        } catch (Throwable throwable) {
            logger.error("", throwable);
            return null;
        }
    }


    public static void check(StringInput stringInput, RedisComponentInterface redisComponentInterface) {
        ControlData ctrlData = stringInput.getCtrlData();
        String inputToken = ctrlData.getxToken();
        String sessionId = ctrlData.getSessionId();

        if (StringUtils.isEmpty(inputToken)) {
            return;
        }

        String newValue = LongStringIdUtil.generateId();
        boolean setResult = redisComponentInterface.setIfSame(Constants.SESSION_REQUEST_EXTRA_AUTH_TOKEN_KEY, sessionId, inputToken, newValue);
        // 合法请求, 重新设置过期时间
        if (setResult) {
            redisComponentInterface.expire(Constants.SESSION_REQUEST_EXTRA_AUTH_TOKEN_KEY, sessionId, 3600);
        }
        // 并发的相同请求
        else {
            throw new BusinessException(com.dap.commons.Constants.ResponseCode.GENERAL_EXCEPTION, "重复请求");
        }
    }

}
